

import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:dolqun_movies/Configs.dart';
import 'package:dolqun_movies/Entities/FilterPreDataResult.dart';
import 'package:dolqun_movies/Entities/LatestMovies.dart';
import 'package:dolqun_movies/Entities/Movie.dart';
import 'package:dolqun_movies/Entities/MovieDetailsResult.dart';
import 'package:dolqun_movies/Entities/RequestPaymentResponse.dart';
import 'package:dolqun_movies/Entities/SignInWithWechat.dart';
import 'package:dolqun_movies/Entities/UserInformationResult.dart';
import 'package:dolqun_movies/Entities/VipInformationResult.dart';
import 'package:dolqun_movies/StateManagement/ModelProvider.dart';

class NetworkInterface with Model {
  Dio _dio;

  NetworkInterface({String url}) {
    this._dio = Dio(BaseOptions(
      baseUrl: url,
    ));
  }

  Future<MoviesResponse> getHomeList() async {
    var response = await _dio.get<String>("/2.0/API.do?action=home_list");
    var data = MoviesResponse.fromJson(json.decode(response.data));
    return data;
  }

  Future<LatestResponse> getLatestVideos() async {
    var response = await _dio.get<String>("/2.0/API.do?action=latest_list");
    return LatestResponse.fromJson(json.decode(response.data));
  }

  Future<LatestResponse> getRecommendedMovies() async {
    var response = await _dio.get<String>("/2.0/API.do?action=ad_list&type=1");
    var jsonMap = json.decode(response.data);
    (jsonMap["data"] as List<dynamic>).forEach((element) {
      var item = element as Map<String, dynamic>;
      item["name"] = item["title"];
      item["rate"] = 0.0;
      item.remove("title");
    });
    return LatestResponse.fromJson(jsonMap);
  }
  Future<LatestResponse> getRelatedMovies(int movieId) async {
    var response = await _dio.get<String>("/2.0/API.do?action=related_list&specialid=$movieId");
    return LatestResponse.fromJson(json.decode(response.data));
  }
  Future<MovieDetailsResult> getMovieDetails(String token, int movieId) async {
    var response = await _dio.get("/2.0/API.do?action=special_data&specialid=$movieId&token=$token");
    return MovieDetailsResult.fromJson(json.decode(response.data));
  }
  Future<List<FilterPreData>> getFilterPreData() async {
    var response = await _dio.get("/2.0/API.do?action=filter_list");
    return FilterPreDataResult.fromJson(json.decode(response.data)).data;
  }
  Future<LatestResponse> getFilteredMovies(int type, List<int> childTypes, int pageIndex) async {
    var data = {
      "typeid": type,
      "ids": childTypes.join("@"),
      "page": pageIndex
    };
    var response = await _dio.post("/2.0/API.do?action=filter_data", queryParameters: data);
    var result = LatestResponse.fromJson(json.decode(response.data));
    if (result.code != 0) throw result.msg;
    return result;
  }
  Future<LatestResponse> getMoviesByKeyWord(String keyword, int pageIndex) async {
    var response = await _dio.get("/2.0/API.do?action=search_list&search=$keyword&page=$pageIndex");
    var result = LatestResponse.fromJson(json.decode(response.data));
    if (result.code != 0) throw result.msg;
    return result;
  }
  Future<SignInWithWechatResult> signInWithWechat(String code) async {
    var response = await _dio.get("/2.0/API.do?action=wechat_login&appid=${Configs.APP_ID}&code=$code");
    var result = SignInWithWechatResult.fromJson(json.decode(response.data));
    return result;
  }
  Future<UserInformationResult> getUSerInformation(String token) async {
    var response = await _dio.get("/2.0/API.do?action=user_info&token=$token");
    return UserInformationResult.fromJson(json.decode(response.data));
  }
  Future<VipInformationResult> getVipListInformation(String token) async {
    var response = await _dio.get("/2.0/API.do?action=vip_list&token=$token");
    return VipInformationResult.fromJson(json.decode(response.data));
  }
  Future<LatestResponse> getMoviesThatAlreadyPaymented(String token, int page) async {
    var response = await _dio.post("/2.0/API.do?action=buy_list&token=$token&page=$page");
    var result = LatestResponse.fromJson(json.decode(response.data));
    if (result.code != 0) throw result.msg;
    return result;
  }
  Future<LatestResponse> getMoviesThatFavoritde(String token, int page) async {
    var response = await _dio.post("/2.0/API.do?action=save_list&token=$token&page=$page");
    var result = LatestResponse.fromJson(json.decode(response.data));
    if (result.code != 0) throw result.msg;
    return result;
  }
  Future<bool> favoriteUnfavoriteMovie(String token, int id) async {
    var response = await _dio.post("/2.0/API.do?action=save_action", queryParameters: {
      "specialid": id,
      "token": token
    });
    var result = json.decode(response.data);
    if (result["code"] != 0) throw result["msg"];
    return result["data"]["state"];
  }
  Future<RequestPaymentResult> requestPayment(PaymentFor forWhat, int destinationId, String token) async {
    var mode = 0;
    if (forWhat == PaymentFor.VIP) mode = 1;
    if (forWhat == PaymentFor.SingleMediaSegment) mode = 2;
    if (forWhat == PaymentFor.WholeMediaSegment) mode = 3;
    var parameter = {
      "mode": mode,
      "id": destinationId,
      "token": token
    };
    var response = await _dio.post("/2.0/API.do?action=wechat_pay", queryParameters: parameter);
    var result = RequestPaymentResult.fromJson(json.decode(response.data));
    if (result.code != 0) {
      throw result.msg;
    }
    return result;
  }
  Future<void> cancelPaymentOrder(String token, String outTradeNumber) async {
    var parameter = {
      "token": token,
      "out_trade_no": outTradeNumber
    };
    var response = await _dio.post("/2.0/API.do?action=cancel_pay", queryParameters: parameter);
    var result = RequestPaymentResult.fromJson(json.decode(response.data));
    if (result.code != 0) {
      print(parameter);
      throw result.msg;
    }
  }
}

enum PaymentFor {
  VIP,
  SingleMediaSegment,
  WholeMediaSegment
}